package com.tbit.uqbike.webmanager.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tbit.common.constant.MethodEnum;
import com.tbit.common.constant.ModuleEnum;
import com.tbit.common.entity.view.Result;
import com.tbit.common.enums.OperaPswEnum;
import com.tbit.common.utils.TraceUtil;
import com.tbit.uqbike.annos.OperateLog;
import com.tbit.uqbike.constant.OperaPswConstant;
import com.tbit.uqbike.constant.TimeFeeConstant;
import com.tbit.uqbike.constant.UserConstant;
import com.tbit.uqbike.enums.SystemCodeEnum;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.business.MachineImportInfo;
import com.tbit.uqbike.object.business.PageData;
import com.tbit.uqbike.object.pojo.AddCountFee;
import com.tbit.uqbike.object.pojo.MachineBaseInfo;
import com.tbit.uqbike.object.pojo.User;
import com.tbit.uqbike.object.pojo.dto.ExpectFeeDto;
import com.tbit.uqbike.object.pojo.dto.MachineRemindDTO;
import com.tbit.uqbike.object.pojo.dto.MachineSearchDTO;
import com.tbit.uqbike.object.pojo.vo.BatchMoveMachineExportVO;
import com.tbit.uqbike.object.pojo.vo.BatchMoveMachineReqVO;
import com.tbit.uqbike.object.pojo.vo.BatchMoveMachineRespVO;
import com.tbit.uqbike.object.pojo.vo.BatchOperationMsgVO;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.object.value.TimeFee;
import com.tbit.uqbike.object.view.JsonResult;
import com.tbit.uqbike.service.base.MachineService;
import com.tbit.uqbike.service.business.OperaPswService;
import com.tbit.uqbike.service.business.UserService;
import com.tbit.uqbike.webmanager.req.machine.QueryByPointReq;
import com.tbit.uqbike.webmanager.util.ExportExcelUtils;
import com.tbit.uqbike.webmanager.util.HttpClientUtils;
import com.tbit.uqbike.webmanager.util.RechargeExportUtil;
import com.tbit.uqbike.webmanager.util.ServletUtils;
import com.tbit.uqbike.webmanager.util.excel.ExcelUtil;
import com.tbit.uqbike.webmanager.util.excel.ExportExcelUtil;
import com.tbit.uqbike.webmanager.util.excel.ExportExcelWrapper;
import com.tbit.utils.HolidayUtils;
import com.tbit.utils.NullUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.RequestContext;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.IOException;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author MyWin E-mail:335918956@qq.com
 * @version 1.0
 * @createTime 2019-12-14 11:14
 */
@Slf4j
@Validated
@RestController
@RequestMapping(value = "/machine", produces = BaseController.MEDIA_JSON_UTF8)
public class MachineController extends BaseController {
    @Autowired
    private UserService userService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private OperaPswService operaPswService;

    /* 添加单个设备*/
    @RequestMapping("/addMachine")
    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.ADD_MACHINE)
    public JsonResult addMachine(@NotNull(message = "ver.machineNO.notNull") String machineNO,
                                 @NotNull(message = "ver.userCode.notNull") String userCode,
                                 String frame, String license, String motor, String remark,
                                 @NotNull(message = "ver.accountId.notNull") Integer accountId,
                                 Integer machineType,
                                 @NotNull(message = "ver.batteryModelId.notNull") Integer batteryModelId,
                                 Integer secondaryBattertId, String functionStr,
                                 HttpServletRequest request) {
        LoginInfo info = getLogin(request);
        if (null == accountId) {
            if (Objects.equals(info.type, UserConstant.USER_AGENT)) {
                accountId = info.id;
            } else {
                throw new BaseException(SystemCodeEnum.ACCOUNT_ID_NOT_VALID);
            }
        }
        Integer[] functionList = Optional.ofNullable(functionStr).filter(StringUtils::isNotBlank).map(x -> x.split(","))
                .map(x -> Arrays.stream(x).map(Integer::valueOf).collect(Collectors.toList()))
                .map(x -> x.toArray(new Integer[0]))
                .orElse(null);

        List<MachineImportInfo> infos = new LinkedList<>();
        infos.add(new MachineImportInfo(machineNO, userCode, frame, license, motor, remark));
        addMachine(info, infos, accountId, machineType, batteryModelId, secondaryBattertId, functionList);
        return JsonResult.ok();
    }

    /* 批量导入设备*/
    @RequestMapping("/importMachines")
    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.ADD_MACHINE)
    public JsonResult importMachines(@NotNull(message = "ver.accountId.notNull") Integer accountId,
                                     Integer machineType, @NotNull(message = "ver.batteryModelId.notNull") Integer batteryModelId, Integer secondaryBattertId,
                                     @RequestParam("file") MultipartFile[] files, Integer[] functionList,
                                     HttpServletRequest request) {
        LoginInfo info = getLogin(request);
        List<MachineImportInfo> list = getInfo(files, 1);
        addMachine(info, list, accountId, machineType, batteryModelId, secondaryBattertId, functionList);
        // 获取参数和文件
        return JsonResult.ok(list.size());
    }

    /* 修改设备*/
    @RequestMapping("/updateMachine")
    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.MOD_MACHINE)
    public JsonResult updateMachine(@NotNull(message = "ver.userCode.notNull") String userCode,
                                    String frame, String license, String motor, String remark,
                                    HttpServletRequest request) {
        LoginInfo info = getLogin(request);

        machineService.modFrame(info, userCode, frame, license, motor, remark);
        // 获取参数和文件
        return JsonResult.ok();
    }

    /* 批量修改设备*/
    @RequestMapping("/updateMachines")
    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.MOD_MACHINE)
    public JsonResult updateMachines(@RequestParam("file") MultipartFile[] files,
                                     HttpServletRequest request) {
        LoginInfo info = getLogin(request);
        List<MachineImportInfo> list = getInfo(files, 0);
//        BatchOperationMsgVO<String> batchOperationMsgVO = machineService.modBatch(info, list);
        BatchOperationMsgVO<String> batchOperationMsgVO = machineService.modBatchv2(info, list);
        // 获取参数和文件
        return JsonResult.ok(batchOperationMsgVO);
    }

    /**
     * 获取excel文件数据
     *
     * @param files
     * @return
     */
    public List<MachineImportInfo> getInfo(MultipartFile[] files, Integer type) {
        if (null == files || files.length == 0) {
            throw new BaseException(SystemCodeEnum.HAVE_NOT_FILE);
        }
        List<List<String>> data = null;
        try {
            data = ExportExcelUtils.readExcelDataFirst(files[0].getBytes(), type);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        if (null == data) {
            throw new BaseException(SystemCodeEnum.READ_FILE_ERROR);
        }
        List<MachineImportInfo> list;
        if (type == 1) {
            list = MachineImportInfo.turnAddMachineList(data);
        } else {
            list = MachineImportInfo.turnEditMachineList(data);
        }

        if (list.isEmpty()) {
            throw new BaseException(SystemCodeEnum.COLL_IS_EMPTY);
        }
        return list;
    }

    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.ADD_MACHINE)
    public void addMachine(LoginInfo info, List<MachineImportInfo> machineInfoList, Integer accountId, Integer machineType,
                           Integer batteryModelId, Integer secondaryBattertId, Integer[] functionList) {
        machineService.addMachine(info, machineInfoList, machineType, accountId, batteryModelId, secondaryBattertId, functionList);
    }

    /* 导出设备信息模板*/
    @RequestMapping(value = "/exportMachineInfoTemplate")
    public JsonResult exportMachineInfoTemplate(HttpServletRequest request, HttpServletResponse response) {
        // 下载模板文件
        LoginInfo info = getLogin(request);
        String machineNOCol = info.context.getMessage(MachineImportInfo.COL_MACHINENO_CODE);
        String userCodeCol = info.context.getMessage(MachineImportInfo.COL_USERCODE_CODE);
        /**车架号*/
        String frame = info.context.getMessage(MachineImportInfo.COL_FRAME_CODE);
        /**车牌号*/
        String license = info.context.getMessage(MachineImportInfo.COL_LICENSE_CODE);
        /**电机号*/
        String motor = info.context.getMessage(MachineImportInfo.COL_MOTOR_CODE);
        /**车辆描述*/
        String remark = info.context.getMessage(MachineImportInfo.COL_REMARK_CODE);
        List<String[]> listContent = new LinkedList<>();
        String[] headers = {machineNOCol, userCodeCol, frame, license, motor, remark};
        String[] items = new String[]{"abcd2345", "135790246", "3213", "粤B12234", "12312", "32131"};
        listContent.add(items);
        items = new String[]{"abcd1234", "135790247", "3213", "粤B12234", "12312", "32131"};
        listContent.add(items);
        ExportExcelWrapper<String[]> export = new ExportExcelWrapper<>();
        export.exportExcel("template", "template", headers, listContent, response, ExportExcelUtil.EXCEl_FILE_2007);
        return JsonResult.ok();
       /* byte[] data = ExportExcelUtils.exportExcelData(new String[]{machineNOCol, userCodeCol}, listContent);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "template.xls");*/
//        return new ResponseEntity<>(data, headers, HttpStatus.OK);
    }


    /* 导出更新设备信息模板*/
    @RequestMapping(value = "/editMachineInfoTemplate")
    public JsonResult editMachineInfoTemplate(HttpServletRequest request, HttpServletResponse response) {
        // 下载模板文件
        LoginInfo info = getLogin(request);
        String userCodeCol = info.context.getMessage(MachineImportInfo.COL_USERCODE_CODE);
        /**车架号*/
        String frame = info.context.getMessage(MachineImportInfo.COL_FRAME_CODE);
        /**车牌号*/
        String license = info.context.getMessage(MachineImportInfo.COL_LICENSE_CODE);
        /**电机号*/
        String motor = info.context.getMessage(MachineImportInfo.COL_MOTOR_CODE);
        /**车辆描述*/
        String remark = info.context.getMessage(MachineImportInfo.COL_REMARK_CODE);
        List<String[]> listContent = new LinkedList<>();
        String[] headers = {userCodeCol, frame, license, motor, remark};
        String[] items = new String[]{"135790246", "3213", "粤B12234", "12312", "32131"};
        listContent.add(items);
        items = new String[]{"135790247", "3213", "粤B12234", "12312", "32131"};
        listContent.add(items);
        ExportExcelWrapper<String[]> export = new ExportExcelWrapper<>();
        export.exportExcel("editTemplate", "editTemplate", headers, listContent, response, ExportExcelUtil.EXCEl_FILE_2007);
        return JsonResult.ok();
       /* byte[] data = ExportExcelUtils.exportExcelData(new String[]{machineNOCol, userCodeCol}, listContent);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "template.xls");*/
//        return new ResponseEntity<>(data, headers, HttpStatus.OK);
    }

    /**
     * 删除设备
     */
    @RequestMapping("/delMachine")
    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.DEL_MACHINE)
    public JsonResult delMachine(@NotNull(message = "ver.machineId.notNull") Integer machineId, String operaPsw, HttpServletRequest request) {
        LoginInfo info = getLogin(request);

        /**操作密码校验*/
        operaPswService.checkOperaPsw(info, OperaPswEnum.OPERA_PSW_OPERATION_CONFIG.getModule(), operaPsw);

        machineService.delMachine(info, machineId);
        return JsonResult.ok();
    }

    /* 修改设备编号*/
    @RequestMapping("/modMachineNO")
    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.MOD_MACHINE_MACHINENO)
    public JsonResult modMachineNO(@NotNull(message = "ver.machineId.notNull") Integer machineId,
                                   @NotNull(message = "ver.machineNO.notNull") String machineNO,
                                   HttpServletRequest request) {
        LoginInfo info = getLogin(request);
        machineService.modMachineNO(info, machineId, machineNO);
        return JsonResult.ok();
    }

    /* 修改用户码*/
    @RequestMapping("/modUserCode")
    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.MOD_MACHINE_USERCODE)
    public JsonResult modUserCode(@NotNull(message = "ver.machineId.notNull") Integer machineId,
                                  @NotNull(message = "ver.userCode.notNull") String userCode, String frame, String license,
                                  String motor,@Size(max = 45, message = "备注长度不能超过45") String remark,
                                  HttpServletRequest request) {
        LoginInfo info = getLogin(request);
        machineService.modUserCode(info, machineId, userCode, frame, license, motor, remark);
        return JsonResult.ok();
    }

    /* 获取设备列表*/
    @RequestMapping("/searchMachine")
    public JsonResult searchMachine(String key, @RequestParam(required = false )String accountIds, Integer machineType, Integer rowCount, String machineNOs,
                                    Integer pageNO, String frame, String license, String motor, HttpServletRequest request,
                                    @RequestParam(defaultValue = "0") Integer dataType,String batteryNo,@RequestParam(required = false )List<Integer> tagIds, Integer machineGroupId, Integer type) {
        LoginInfo info = getLogin(request);
        if (pageNO == null) {
            pageNO = 1;
        }
        if (rowCount == null) {
            rowCount = 10;
        }
        PageData<List<MachineBaseInfo>> pageData = machineService.searchMachine(info, accountIds, key, machineNOs, rowCount, pageNO, machineType, frame, license, motor,dataType,batteryNo,tagIds, machineGroupId, type);
        return JsonResult.ok(pageData.getData(), pageData.getTotal());
    }

    /* 获取设备列表(根据type来确定是 用户编号还是 )*/





    /* 获取设备列表*/
    /*@RequestMapping("/exportMachine")
    public void exportMachine(String key, @RequestParam(required = false )String accountIds, Integer machineType, Integer rowCount, String machineNOs,
                              Integer pageNO, String frame, String license, String motor, HttpServletRequest request,
                              @RequestParam(defaultValue = "0") Integer dataType,String batteryNo,@RequestParam(required = false )List<Integer> tagIds,
                              HttpServletResponse response, Integer machineGroupId, Integer type) {
        LoginInfo info = getLogin(request);
        RequestContext context = info.getContext();
        pageNO = 1;
        rowCount = 65536;
        PageData<List<MachineBaseInfo>> pageData = machineService.searchMachine(info, accountIds, key, machineNOs, rowCount, pageNO, machineType, frame,
                license, motor,dataType,batteryNo,tagIds, machineGroupId, type);
        List<MachineBaseInfo> list =  pageData.getData();
        List<String[]> data = RechargeExportUtil.getMachineExportContent(list, context);
        ExportExcelWrapper<String[]> export = new ExportExcelWrapper<>();
        export.exportExcel(context.getMessage("excel_head_machine_information"), context.getMessage("excel_head_machine_information"), null, data, response, ExportExcelUtil.EXCEL_FILE_2003);
    }*/

    /**
     * @description: 导出车辆列表
     * @author: mo.shanyong
     * @date: 2024/12/6 15:49
     * @param: searchDTO 搜索参数
     * @param: request
     * @param: response
     */
    @RequestMapping("/exportMachine")
    public void exportMachine(MachineSearchDTO searchDTO,HttpServletRequest request,HttpServletResponse response) {
        LoginInfo info = getLogin(request);
        RequestContext context = info.getContext();
        searchDTO.setPageNO(1);
        searchDTO.setRowCount(65536);
        searchDTO.setInfo(info);
        log.info("exportMachine----->{}",JSON.toJSONString(searchDTO));
        PageData<List<MachineBaseInfo>> pageData = machineService.searchMachineV2(searchDTO);
        List<MachineBaseInfo> list =  pageData.getData();
        List<String[]> data = RechargeExportUtil.getMachineExportContent(list, context);
        ExportExcelWrapper<String[]> export = new ExportExcelWrapper<>();
        export.exportExcel(context.getMessage("excel_head_machine_information"), context.getMessage("excel_head_machine_information"), null, data, response, ExportExcelUtil.EXCEL_FILE_2003);
    }

    /* 导出修改设备信息模板*/
    @RequestMapping(value = "/exportModMachineInfoTemplate")
    public JsonResult exportModMachineInfoTemplate(HttpServletRequest request, HttpServletResponse response) {
        // 下载模板文件
        LoginInfo info = getLogin(request);
        String userCodeCol = info.context.getMessage(MachineImportInfo.COL_USERCODE_CODE);
        String statusCodeCol = info.context.getMessage(MachineImportInfo.COL_STATUS_CODE);
        List<String[]> data = new LinkedList<>();
        String[] headers = {userCodeCol, statusCodeCol};
        String[] items = new String[]{"135790246", "YES"};
        data.add(items);
        items = new String[]{"135790247", "NO"};
        data.add(items);
        ExportExcelWrapper<String[]> export = new ExportExcelWrapper<>();
        export.exportExcel("mod_template", "mod_template", headers, data, response, ExportExcelUtil.EXCEl_FILE_2007);
        return JsonResult.ok();
        /*byte[] data = ExportExcelUtils.exportExcelData(new String[]{userCodeCol, statusCodeCol}, listContent);
        HttpHeaders headers = new HttpHeaders();

        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "mod_template.xls");

        return new ResponseEntity<>(data, headers, HttpStatus.OK);*/
    }

    /* 修改设备投放状态*/
    @RequestMapping("/modMachineState")
    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.MOD_MACHINE_STATE)
    public JsonResult modMachineState(@NotNull(message = "ver.userCode.notNull") String userCode, String status,
                                      HttpServletRequest request) {
        LoginInfo info = getLogin(request);
        List<MachineImportInfo> infos = new LinkedList<>();
        infos.add(MachineImportInfo.initModInfo(userCode, status));
        modMachineStatus(info, infos);
        return JsonResult.ok();
    }

    /* 批量修改设备投放状态*/
    @RequestMapping("/importMachineState")
    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.MOD_MACHINE_STATE)
    public JsonResult modMachineState(@RequestParam("file") MultipartFile[] files, HttpServletRequest request) {
        LoginInfo info = getLogin(request);
        if (null == files || files.length == 0) {
            throw new BaseException(SystemCodeEnum.HAVE_NOT_FILE);
        }
        List<List<String>> data = null;
        try {
            data = ExportExcelUtils.readExcelData(files[0].getBytes());
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
        if (null == data) {
            throw new BaseException(SystemCodeEnum.READ_FILE_ERROR);
        }
        List<MachineImportInfo> list = MachineImportInfo.turnModMachineList(data);
        if (list.isEmpty()) {
            throw new BaseException(SystemCodeEnum.COLL_IS_EMPTY);
        }
        modMachineStatus(info, list);
        // 获取参数和文件
        return JsonResult.ok(list.size());
    }

    public void modMachineStatus(LoginInfo info, List<MachineImportInfo> machineInfoList) {
        machineService.modMachineStatus(info, machineInfoList);
    }


    /* 获取预估费用*/
    @RequestMapping("/getFee")
    public JsonResult getFee(Integer accountId, Integer adAccountId, @NotNull(message = "ver.phone.notNull") String phone) {
        User user = null;
        if (accountId != null) {
            user = userService.getByAccountPhone(accountId, phone);
        } else if (adAccountId != null) {
            user = userService.getByAdaccountId(adAccountId, phone);
        }
        if (user == null) {
            throw new BaseException(SystemCodeEnum.USER_NOT_EXIT);
        }
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("userId", user.getUserId().toString()));

        String json = HttpClientUtils.httpPost(OperaPswConstant.ACCOUNT_OPERA_CLIENT_URL + "/machine/getFee.do", null, params);
        //log.info(json);
        if (!NullUtils.isEmpty(json)) {
            JSONObject jsonObject = JSONObject.parseObject(json);
            String data = jsonObject.getString("data");
            return JsonResult.ok(data);
        }
        return JsonResult.fail("获取预估费用失败", TraceUtil.getTraceIdByLocal());
    }


    /* 获取预估费用*/
    @RequestMapping("/getExpectFee")
    public JsonResult getExpectFee(Integer time, Double mileage, Integer adAccountId) {
        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("adAccountId", adAccountId.toString()));
        params.add(new BasicNameValuePair("time", time.toString()));
        params.add(new BasicNameValuePair("mileage", mileage.toString()));
        String json = HttpClientUtils.httpPost(OperaPswConstant.ACCOUNT_OPERA_CLIENT_URL + "/machine/getExpectFee.do", null, params);
        log.info(json);
        JSONObject jsonObject = JSONObject.parseObject(json);
        String data = jsonObject.getString("data");
        System.out.println(data);

        return JsonResult.ok(data);
    }


    /* 获取预估费用*/
    @RequestMapping("/getExpectFeeNew")
    public JsonResult getExpectFeeNew(@RequestBody ExpectFeeDto dto) {
        /*List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("adAccountId", dto.getAdAccountId().toString()));
        params.add(new BasicNameValuePair("time", dto.getTime().toString()));
        params.add(new BasicNameValuePair("mileage", dto.getMileage().toString()));
        params.add(new BasicNameValuePair("addCountFee", dto.getAddCountFee().toString()));
        String json = HttpClientUtils.httpPost(OperaPswConstant.ACCOUNT_OPERA_CLIENT_URL + "/machine/getExpectFee.do", null, params);*/
        JSONObject object = dto.getObject();
        //区域计费
        AddCountFee addCountFee = Optional.ofNullable(object.getString("area")).map(s -> JSON.parseObject(s,AddCountFee.class)).orElse(null);
        //分时计费
        List<TimeFee> timeFees =Optional.ofNullable(object.getString("time")).map(s -> JSON.parseArray(s,TimeFee.class)).orElse(new ArrayList<>());
        // 假日计费
        List<TimeFee> holidayTimeFees = Optional.ofNullable(object.getString("holiday")).map(s -> JSON.parseArray(s, TimeFee.class)).orElse(new ArrayList<>());
        // 假日计费页面上的 区域默认计费进行覆盖
        if (Objects.isNull(addCountFee)){
            addCountFee = holidayTimeFees.stream().filter(x -> Objects.equals(x.getType(), TimeFeeConstant.HOLIDAY_AREA_FEE)).findFirst().map(x -> {
                AddCountFee fee = new AddCountFee();
                BeanUtils.copyProperties(x,fee);
                return fee;
            }).orElse(new AddCountFee());
        }
        // 假日计费页面上的 区域分时计费进行覆盖
        if (timeFees.isEmpty()){
            timeFees = holidayTimeFees.stream().filter(x -> Objects.equals(x.getType(), TimeFeeConstant.HOLIDAY_AREA_TIME_FEE)).map(x -> {
                TimeFee fee = new TimeFee();
                BeanUtils.copyProperties(x,fee);
                return fee;
            }).collect(Collectors.toList());
        }
        Integer hour = null;
        if (Objects.nonNull(dto.getBeginTime())) {
            // 判断命中哪个  假日 / 周末 ， 将timeFees 用 假日或周末的  分时计费规则替换
            String day = getDateValue(dto.getBeginTime(), "day");
            hour = Integer.parseInt(getDateValue(dto.getBeginTime(),"hour"));
            String dayOfWeek = getDateValue(dto.getBeginTime(),"dayOfWeek");
            // 是周末且非调休
            if (!HolidayUtils.validWorkOnWeekend(day) && (Objects.equals(dayOfWeek,String.valueOf(DayOfWeek.SATURDAY)) || Objects.equals(dayOfWeek,String.valueOf(DayOfWeek.SUNDAY))) ){
                // 升序排序保证默认计费在前
                timeFees = holidayTimeFees.stream().filter(x -> Arrays.asList(TimeFeeConstant.HOLIDAY_WEEKEND_FEE,TimeFeeConstant.HOLIDAY_WEEKEND_TIME_FEE).contains(x.getType())).sorted(Comparator.comparingInt(TimeFee::getType)).collect(Collectors.toList());
            }
            // 是节假日
            if (HolidayUtils.validHoliday(day)) {
                // 过滤节假日的分时计费 ， 升序排序保证默认计费在前
                timeFees = holidayTimeFees.stream().filter(x -> Arrays.asList(TimeFeeConstant.HOLIDAY_FEE,TimeFeeConstant.HOLIDAY_TIME_FEE).contains(x.getType())).sorted(Comparator.comparingInt(TimeFee::getType)).collect(Collectors.toList());
            }
        }

        // 分时
        for(TimeFee timeFee:timeFees){
            if(timeFee.getBeginTime() <= hour && hour < timeFee.getEndTime()){
                BeanUtils.copyProperties(timeFee,addCountFee);
            }
        }
        String json = HttpRequest
                .post(OperaPswConstant.ACCOUNT_OPERA_CLIENT_URL + "/machine/getExpectFee.do")
                .form("adAccountId", dto.getAdAccountId())
                .form("time", dto.getTime())
                .form("mileage", dto.getMileage())
                .form(JSON.parseObject(JSON.toJSONString(addCountFee), Map.class))
                .execute()
                .body();
        log.info(json);
        JSONObject jsonObject = JSONObject.parseObject(json);
        String data = jsonObject.getString("data");
        System.out.println(data);

        return JsonResult.ok(data);
    }

    /**
     * 获取日期的 年份year /月份month / 日期day / 小时hour / 星期 dayOfWeek
     *
     * @param dateStr 日期字符串 yyyy-MM-dd HH:mm:ss
     * @param valueType 获取的值类型 年份0 /月份1
     * @return 年份 / 月份 / 日期yyyy-MM-dd / 小时 / 星期
     */
    private String getDateValue(String dateStr,String valueType) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.parse(dateStr, formatter);

        switch (valueType){
            case "year":
                return String.valueOf(localDateTime.getYear());
            case "month":
                return String.valueOf(localDateTime.getMonthValue());
            case "day":
                return localDateTime.toLocalDate().toString();
            case "hour":
                return String.valueOf(localDateTime.getHour());
            case "dayOfWeek":
                return String.valueOf(localDateTime.getDayOfWeek());
            default:
                return "-1";
        }
    }

    /**
     * 批量删除设备
     */
    @RequestMapping("/delBatch")
    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.DEL_MACHINE)
    public JsonResult delBatch(String machineNOs, String operaPsw, HttpServletRequest request) {
        LoginInfo info = getLogin(request);
        /**操作密码校验*/
        operaPswService.checkOperaPsw(info, OperaPswEnum.OPERA_PSW_OPERATION_CONFIG.getModule(), operaPsw);

        /**权限校验*/
        if (!info.type.equals(UserConstant.USER_ADMIN)) {
            throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
        }
        /**设备编号获取*/
        List<String> machineNO = Arrays.asList(machineNOs.split(","));


        List<String> notExistNO = machineService.deleteBatch(machineNO);
        System.out.println("不存在设备" + notExistNO);
        if (notExistNO.size() > 0) {
            return JsonResult.ok(notExistNO);
        } else {
            return JsonResult.ok();
        }

    }


    /**
     * 批量删除设备(用户编号也可以查询)
     */
    @RequestMapping("/delBatchNew")
    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.DEL_MACHINE)
    public JsonResult delBatchNew(String machineNOs, String operaPsw,Integer accountId, HttpServletRequest request,Integer dataType) {
        LoginInfo info = getLogin(request);
        /**操作密码校验*/
        operaPswService.checkOperaPsw(info, OperaPswEnum.OPERA_PSW_OPERATION_CONFIG.getModule(), operaPsw);

        /**权限校验*/
        if (!info.type.equals(UserConstant.USER_ADMIN)) {
            throw new BaseException(SystemCodeEnum.NO_PRIVILEGE);
        }
        /**设备编号获取*/
        List<String> machineNO = Arrays.asList(machineNOs.split(","));

        List<String> strings = machineService.deleteBatchNew(machineNO, dataType,accountId);
        return JsonResult.ok(strings);


    }

    /**
     * 通过地图上的多个点(至少三个)查询区域内设备信息
     *
     */
    @PostMapping("/loadMachineByPoints")
    public Result<List<MachineBaseInfo>> loadMachineByPoints(@RequestBody @Valid QueryByPointReq req) {
        return Result.success(machineService.loadMachineByPoints(req));
    }


    /**
     * 批量划拨设备
     *
     * @param reqVO 请求
     */
    @PostMapping("/batchMoveMachine")
    @OperateLog(module = ModuleEnum.TER_MANAGER, methods = MethodEnum.BATCH_MOVE_MACHINE)
    public Result<BatchMoveMachineExportVO> batchMoveMachine(@RequestBody @Valid BatchMoveMachineReqVO reqVO) {
        /**操作密码校验*/
        operaPswService.checkOperaPsw(BaseController.getLogin(ServletUtils.getRequest()),
                    OperaPswEnum.OPERA_PSW_OPERATION_CONFIG.getModule(), reqVO.getOperaPsw());

        Map<String, String> errResult = machineService.batchMoveMachine(reqVO);

        if (CollUtil.isEmpty(errResult)) {
            return Result.success();
        }

        List<BatchMoveMachineRespVO> resp = new ArrayList<>();
        errResult.forEach((k, v) -> {
            BatchMoveMachineRespVO respVO = new BatchMoveMachineRespVO(k, v);
            resp.add(respVO);
        });

        BatchMoveMachineExportVO exportVO = new BatchMoveMachineExportVO();
        exportVO.setBatchMoveMachine(resp);

        //导出excel
        ExcelUtil<BatchMoveMachineRespVO> excelUtil = new ExcelUtil<>(BatchMoveMachineRespVO.class);
        exportVO.setFileName(excelUtil.exportExcel(resp, "失败车辆编号").getData());

        return Result.error(exportVO);
    }

    /**
     * @description: 最新车辆列表搜索
     * @author: mo.shanyong
     * @date: 2024/11/28 16:07
     * @param: searchDTO
     * @param: request
     * @return: com.tbit.uqbike.object.view.JsonResult
     */
    @RequestMapping("/searchMachineV2")
    public JsonResult searchMachineV2(MachineSearchDTO searchDTO,HttpServletRequest request) {
        LoginInfo info = getLogin(request);
        searchDTO.setInfo(info);
//        log.info("searchMachineV2----->{}",JSON.toJSONString(searchDTO));
        PageData<List<MachineBaseInfo>> pageData = machineService.searchMachineV2(searchDTO);
        return JsonResult.ok(pageData.getData(), pageData.getTotal());
    }


    /**
     * 批量操作sim提醒状态
     * @param dto dto
     * @return Result<Object>
     */
    @PostMapping("/updateRemindState")
    public Result<Object> updateRemindState(@RequestBody MachineRemindDTO dto) {
        if (Objects.isNull(dto.getType()) || Objects.isNull(dto.getOperateType())
                || Objects.isNull(dto.getAccountId()) || CollectionUtil.isEmpty(dto.getUserCodeOrMachineNo())){
            return Result.error("参数错误");
        }
        return machineService.updateRemindState(dto);
    }

}
